using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Reflection;
using Microsoft.SharePoint;

namespace SAE.Controls
{
    public partial class RunAdminJobs : UserControl
    {
        private Dictionary<string, string> jobAssemblies;

        public RunAdminJobs()
        {
            InitializeComponent();
            InitJobLists();
            InitWebs();

            this.backgroundWorker.DoWork += new DoWorkEventHandler(backgroundWorker_DoWork);
            this.backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker_RunWorkerCompleted);
        }              

        private void InitJobLists()
        {
            this.jobAssemblies = new Dictionary<string, string>();

            DirectoryInfo di = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory);

            FileInfo[] dllFiles = di.GetFiles("*.dll");

            foreach (FileInfo dllFile in dllFiles)
            {
                try
                {
                    Assembly dllAssembly = Assembly.LoadFile(dllFile.FullName);

                    Type[] types = dllAssembly.GetTypes();

                    foreach (Type type in types)
                    {
                        if (type.IsSubclassOf(typeof(SAE.Plugin.SPSAdminJob)))
                        {
                            this.clbJobs.Items.Add(type.ToString());
                            this.jobAssemblies.Add(type.ToString(), dllFile.FullName);
                        }
                    }
                }
                catch
                {
                }
            }
        }

        private void InitWebs()
        {
            using (SPSite site = new SPSite(SettingConstants.SiteUrl))
            {
                foreach (SPWeb web in site.AllWebs)
                {
                    using (web)
                    {
                        this.clbWebs.Items.Add(web.ServerRelativeUrl);
                    }
                }
            }
        }

        private void clbWebs_ItemCheck(object sender, ItemCheckEventArgs e)
        {
            using (SPSite site = new SPSite(SettingConstants.SiteUrl))
            {
                string selectedWebUrl = this.clbWebs.Items[e.Index].ToString();

                using (SPWeb web = site.OpenWeb(selectedWebUrl))
                {
                    SPListCollection lists = web.GetListsOfType(SPBaseType.DocumentLibrary);

                    if (e.NewValue==CheckState.Checked)
                    {
                        foreach (SPList list in lists)
                        {
                            this.clbLists.Items.Add(list.DefaultViewUrl);
                        }
                    }
                    else
                    {
                        foreach (SPList list in lists)
                        {
                            this.clbLists.Items.Remove(list.DefaultViewUrl);
                        }
                    }
                }
            }
        }

        private void btnRefreshJobList_Click(object sender, EventArgs e)
        {
            this.clbJobs.Items.Clear();

            this.InitJobLists();
        }

        private void btnProcessJobs_Click(object sender, EventArgs e)
        {
            this.btnProcessJobs.Enabled = false;
            this.rtbLog.Clear();

            this.totalProgressBar.Value = 0;
            this.currentProgressBar.Value = 0;

            if (this.clbJobs.SelectedItems.Count > 0)
            {
                foreach (string selectedItem in this.clbJobs.SelectedItems)
                {
                    string assemblyPath = this.jobAssemblies[selectedItem];

                    Assembly dllAssembly = Assembly.LoadFile(assemblyPath);

                    SAE.Plugin.SPSAdminJob job = dllAssembly.CreateInstance(selectedItem) as SAE.Plugin.SPSAdminJob;
                    job.TotalProgressChanged += new SAE.Plugin.SPSAdminJob.ProgressChangedHandler(job_TotalProgressChanged);
                    job.CurrentProgressChanged += new SAE.Plugin.SPSAdminJob.ProgressChangedHandler(job_CurrentProgressChanged);
                    job.CurrentProgressResetted += new EventHandler(job_CurrentProgressResetted);

                    if (this.clbLists.SelectedItems.Count > 0)
                    {
                        using (SPSite site = new SPSite(SettingConstants.SiteUrl))
                        {
                            foreach (string listUrl in this.clbLists.SelectedItems)
                            {
                                string currentWebUrl = string.Empty;

                                foreach (string webUrl in this.clbWebs.Items)
                                {
                                    if (listUrl.StartsWith(webUrl))
                                    {
                                        currentWebUrl = webUrl;
                                        break;
                                    }
                                }

                                using (SPWeb web = site.OpenWeb(currentWebUrl))
                                {
                                    SPList list = web.GetListFromUrl(listUrl);
                                    job.Run(list);
                                }
                            }
                        }


                    }
                    else if (this.clbWebs.SelectedItems.Count > 0)
                    {
                        foreach (string webUrl in this.clbWebs.SelectedItems)
                        {
                            using (SPSite site = new SPSite(SettingConstants.SiteUrl))
                            {
                                using (SPWeb web = site.OpenWeb(webUrl))
                                {
                                    job.Run(web);
                                }
                            }
                        }
                    }
                    else
                    {
                        using (SPSite site = new SPSite(SettingConstants.SiteUrl))
                        {
                            job.Run(site);
                        }
                    }
                }
            }

            this.btnProcessJobs.Enabled = true;
        }

        void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
                    
        }

        void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            this.btnProcessJobs.Enabled = true;
        }

        void job_CurrentProgressResetted(object sender, EventArgs e)
        {
            this.currentProgressBar.Value = 0;
        } 

        void job_CurrentProgressChanged(object sender, SAE.Plugin.AdminJobEventArgs e)
        {
            this.rtbLog.AppendText(string.Format("[{0}]:",DateTime.Now)+e.ProgressMessage);
            this.rtbLog.AppendText(Environment.NewLine);
            this.rtbLog.Refresh();

            this.currentProgressBar.Maximum = e.Maximum;
            this.currentProgressBar.Step = e.Step;
            this.currentProgressBar.PerformStep();             
        }

        void job_TotalProgressChanged(object sender, SAE.Plugin.AdminJobEventArgs e)
        {
            this.rtbLog.AppendText(string.Format("[{0}]:",DateTime.Now)+e.ProgressMessage);
            this.rtbLog.AppendText(Environment.NewLine);
            this.rtbLog.Refresh();

            this.totalProgressBar.Maximum = e.Maximum;
            this.totalProgressBar.Step = e.Step;
            this.totalProgressBar.PerformStep();           
        }         

        private void btnSaveLog_Click(object sender, EventArgs e)
        {
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.DefaultExt = ".txt";
            sfd.FileName = "log.txt";
            sfd.Filter = "Text files(*.txt)|*.txt";

            if (sfd.ShowDialog() == DialogResult.OK)
            {
                this.rtbLog.SaveFile(sfd.FileName,RichTextBoxStreamType.UnicodePlainText);
            }
        }     
    }
}
